/*
  Switch Lab Center
  Copyright (C) www.labotroniK.com

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "switchlab.h"
#include "ui_switchlab.h"
#include <QtNetwork>
#include <QDebug>

int delay_udp_ms=20;


SwitchLab::SwitchLab(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::SwitchLab)
{
    ui->setupUi(this);

    ui->buttonGroup->addButton(ui->btnRelay_1,1);
    ui->buttonGroup->addButton(ui->btnRelay_2,2);
    ui->buttonGroup->addButton(ui->btnRelay_3,3);
    ui->buttonGroup->addButton(ui->btnRelay_4,4);
    ui->buttonGroup->addButton(ui->btnRelay_5,5);
    ui->buttonGroup->addButton(ui->btnRelay_6,6);
    ui->buttonGroup->addButton(ui->btnRelay_7,7);
    ui->buttonGroup->addButton(ui->btnRelay_8,8);
    connect(ui->buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(toggleRelayRequest(int))) ;

    ui->inputGroup->addButton(ui->btnInput_1,1);
    ui->inputGroup->addButton(ui->btnInput_2,2);
    ui->inputGroup->addButton(ui->btnInput_3,3);
    ui->inputGroup->addButton(ui->btnInput_4,4);
    ui->inputGroup->addButton(ui->btnInput_5,5);
    ui->inputGroup->addButton(ui->btnInput_6,6);
    ui->inputGroup->addButton(ui->btnInput_7,7);
    ui->inputGroup->addButton(ui->btnInput_8,8);

    udpSocket = new QUdpSocket(this);
    boardip  =  new QHostAddress(ui->IPaddress->text());
    initSocket();
    getInfo();


    timerState = new QTimer(this);
    timerState->setInterval(80);
    timerState->start();
    connect(timerState, SIGNAL(timeout()), this, SLOT(getBoardStatus()));
}

void SwitchLab::toggleRelayRequest(int btnID)
{
    int btnpressedGroup;
    btnpressedGroup = ui->buttonGroup->checkedId();


    if (btnID==btnpressedGroup){
       // qDebug() << "set relay" << btnPressed;
       setRelay(btnID);
    }
    else {
       // qDebug() << "clear relay" << btnPressed;
       clearRelay(btnID);
    }
}

void SwitchLab::setRelay(int relayID)
{
    char tmpChar[4]="SRx";
    tmpChar[2]=relayID+48; //ASCII conversion of relay ID
    sendUDP(tmpChar);
    qDebug()<< "send" <<tmpChar;

}

void SwitchLab::clearRelay(int relayID)
{
    char tmpChar[4]="CRx";
    tmpChar[2]=relayID+48; //ASCII conversion of relay ID
    tmpChar[3]='\0';
    sendUDP(tmpChar);
    qDebug()<< "send" <<tmpChar;
}


void SwitchLab::sendUDP(const char* myvalue )
{

    bool ok;
    QString strUDPport = ui->UDPport->text();
    int UDPport = strUDPport.toInt(&ok, 10);

    //udpSocket->connectToHost(*boardip,UDPport);
    udpSocket->writeDatagram(myvalue,*boardip,UDPport);
    //qDebug()<<"send" << myvalue;
}


void SwitchLab::getBoardStatus(void) {
        uint relayState;
        uint inputState;
        uint i;
        uint ptr=1;

        relayState = getRelay();
        inputState = getInput();
        ptr=1;
        for (i=1;i<=8;i++) {
            if (relayState & (ptr<<(i-1))){
                ui->buttonGroup->button(i)->setChecked(true);
            }
            else {
                ui->buttonGroup->button(i)->setChecked(false);
            }
        }

        ptr=1;
        qDebug()<<"input state"<< inputState;
        for (i=1;i<=8;i++) {
            if (inputState & (ptr<<(i-1))) {
                ui->inputGroup->button(i)->setChecked(true);

            }
            else {
                ui->inputGroup->button(i)->setChecked(false);

            }
        }
}


int SwitchLab::getRelay(void)
 {
    QByteArray datagram;
    bool ok;

    sendUDP("GRA");
    QEventLoop loop;
    QTimer::singleShot(delay_udp_ms, &loop, SLOT(quit()) );
    loop.exec();
    while (udpSocket->hasPendingDatagrams()) {

             datagram.resize(udpSocket->pendingDatagramSize());

             udpSocket->readDatagram(datagram.data(), datagram.size());
   }
    qDebug()<<"Relay Status:" << datagram.data() ;

    return datagram.toInt(&ok, 10);

}


int  SwitchLab::getInput(void)
 {
    QByteArray datagram;
    bool ok;

    sendUDP("GIA");
    QEventLoop loop;
    QTimer::singleShot(delay_udp_ms, &loop, SLOT(quit()) );
    loop.exec();

    while (udpSocket->hasPendingDatagrams()) {
             datagram.resize(udpSocket->pendingDatagramSize());
             udpSocket->readDatagram(datagram.data(), datagram.size());
   }
    //qDebug()<<"Input Status:" << datagram.data() ;
    return datagram.toInt(&ok, 10);
}


void SwitchLab::getInfo(void)
 {

    QByteArray datagram;
    sendUDP("?");

    QEventLoop loop;
    QTimer::singleShot(delay_udp_ms, &loop, SLOT(quit()) );
    loop.exec();

    while (udpSocket->hasPendingDatagrams()) {

             datagram.resize(udpSocket->pendingDatagramSize());
             udpSocket->readDatagram(datagram.data(), datagram.size());
   }

    //qDebug()<<"Input Status:" << datagram.data() ;
    ui->boardInfo->setText(datagram);

}

/*
void SwitchLab::processPendingDatagrams()
 {

    QByteArray datagram;
    while (udpSocket->hasPendingDatagrams()) {

             datagram.resize(udpSocket->pendingDatagramSize());

             udpSocket->readDatagram(datagram.data(), datagram.size());
   }
    qDebug()<<"receive:" << datagram.data() ;

 }
*/

void SwitchLab::initSocket(void) {

bool ok;
QString strUDPport = ui->UDPport->text();
int lUDPport = strUDPport.toInt(&ok, 10);

disconnect(udpSocket);
//QString tmpIPaddress = ui->IPaddress->text();

boardip  = new QHostAddress(ui->IPaddress->text());

//boardip->setAddress(ui->IPaddress->text());
udpSocket->connectToHost(*boardip,lUDPport);

}



void SwitchLab::on_pushButton_clicked()
{
    initSocket();
    getInfo();
}



SwitchLab::~SwitchLab()
{
    delete ui;
}


